﻿#include<iostream>
#include<memory>
#include<functional>
using namespace std;

//double Divide(int a, int b)
//{
//	// 当b == 0时抛出异常
//	if (b == 0)
//	{
//		throw "Divide by zero condition!";
//	}
//	else
//	{
//		return (double)a / (double)b;
//	}
//}
//void Func()
//{
//	int* array1 = new int[10];
//	int* array2 = new int[10]; 
//	try
//	{
//		int len, time;
//		cin >> len >> time;
//		cout << Divide(len, time) << endl;
//	}
//	catch (...)
//	{
//		cout << "delete []" << array1 << endl;
//		cout << "delete []" << array2 << endl;
//		delete[] array1;
//		delete[] array2;
//		throw; // 异常重新抛出，捕获到什么抛出什么
//	}
//	cout << "delete []" << array1 << endl;
//	delete[] array1;
//	cout << "delete []" << array2 << endl;
//	delete[] array2;
//}
//
////void Func()
////{
////	int* array1 = new int[10];
////	int* array2 = new int[10];
////	int len, time;
////	cin >> len >> time;
////	cout << Divide(len, time) << endl;
////	cout << "delete []" << array1 << endl;
////	delete[] array1;
////	cout << "delete []" << array2 << endl;
////	delete[] array2;
////}
//int main()
//{
//	try
//	{
//		Func();
//	}
//	catch (const char* errmsg)
//	{
//		cout << errmsg << endl;
//	}
//	catch (const exception& e)
//	{
//		cout << e.what() << endl;
//	}
//	catch (...)
//	{
//		cout << "未知异常" << endl;
//	}
//	return 0;
//}

//template<class T>
//class SmartPtr
//{
//public:
//	SmartPtr(T* ptr)
//		:_ptr(ptr){ }
//
//	//单个对象访问资源
//	T& operator*()
//	{
//		return *_ptr;
//	}
//	//结构体这样的对象
//	T* operator->()
//	{
//		return _ptr;
//	}
//	//new[]申请的资源
//	T& operator[](size_t i)
//	{
//		return _ptr[i];
//	}
//
//	~SmartPtr()
//	{
//		cout << "delete:" << _ptr << endl;
//		delete[] _ptr;
//	}
//private:
//	T* _ptr;
//};
//
//double Divide(int a, int b)
//{
//	// 当b == 0时抛出异常
//	if (b == 0)
//	{
//		throw "Divide by zero condition!";
//	}
//	else
//	{
//		return (double)a / (double)b;
//	}
//}
//void Func()
//{
//	SmartPtr<int> sp1 = new int[10];
//	SmartPtr<int> sp2 = new int[10];
//
//	SmartPtr<int> sp3(sp2);
//
//	int len, time;
//	cin >> len >> time;
//	cout << Divide(len, time) << endl;
//	
//}
//
//int main()
//{
//	/*SmartPtr<int> sp1 = new int[10];*/
//	try
//	{
//		Func();
//	}
//	catch (const char* errmsg)
//	{
//		cout << errmsg << endl;
//	}
//	catch (const exception& e)
//	{
//		cout << e.what() << endl;
//	}
//	catch (...)
//	{
//		cout << "未知异常" << endl;
//	}
//	return 0;
//}

struct Date
{
	int _year;
	int _month;
	int _day;
	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{
	}
	~Date()
	{
		cout << "~Date()" << endl;//验证是否会自动释放
	}
};
//
//int main()
//{
//	//auto_ptr<Date> ap1(new Date);
//	//ap1->_day++;
//
//	////管理权转移
//	//auto_ptr<Date> ap2(ap1);
//	//ap2->_day++;
//	////ap1->_day++;//空指针解引用
//
//	//unique_ptr<Date> p1(new Date);
//	////禁止拷贝
//	////unique_ptr<Date> p2(p1);
//	////可以移动
//	//unique_ptr<Date>p2(move(p1));
//
//	//可以拷贝可以移动
//	//shared_ptr<Date> sp1(new Date);
//	//shared_ptr<Date> sp2(sp1);
//	//shared_ptr<Date> sp3(move(sp1));
//
//	cout << sp2.use_count() << endl;//2
//
//
//	return 0;
//}
template<class T>
class DeleteArray
{
	void operator()(T* ptr)
	{
		delete[] ptr;
	}
};

class Fclose
{
	void operator()(FILE* ptr)
	{
		fclose(ptr);
	}
};

int main()
{
	shared_ptr<Date[]> sp1(new Date[10]);
	unique_ptr<Date[]> up1(new Date[10]);

	unique_ptr<Date, DeleteArray<Date>> up2(new Date[10]);
	//C++20支持
	unique_ptr<Date, decltype([](Date* ptr) {delete[] ptr; })> up2(new Date[10]);

	auto del = [](Date* ptr) {delete[] ptr; };
	unique_ptr < Date, decltype(del) > up2(new Date[10],del);



	shared_ptr<Date> sp2(new Date[10], DeleteArray<Date>());
	shared_ptr<Date> sp3(new Date[10], [](Date* ptr) {delete[] ptr; });
	shared_ptr<FILE> sp4(fopen("test.cpp", "r"), Fclose());
	shared_ptr<FILE> sp5(fopen("test.cpp", "r"), [](FILE * ptr)
	{
		fclose(ptr);
	});


	return 0;
}